import calculationsandtests.*;

import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.RowSpec;
import com.jgoodies.forms.factories.FormFactory;

import javax.imageio.ImageIO;
import javax.swing.*;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;

import javax.swing.border.LineBorder;

public class SundialGenerator {
                
                private static String location;
                private static double latitude;
                private static double longitude;
        private JFrame frmSundialGenerator;
        private JTextField txtEnterALocation;

        /**
         * Launch the application.
         */
        public static void main(String[] args) {
                EventQueue.invokeLater(new Runnable() {
                        public void run() {
                                try {
                                        SundialGenerator window = new SundialGenerator();
                                        window.frmSundialGenerator.setVisible(true);
                                } catch (Exception e) {
                                        e.printStackTrace();
                                }
                        }
                });
        }

        /**
         * Create the application.
         */
        public SundialGenerator() {
                initialize();
        }

        /**
         * Initialize the contents of the frame.
         */
        private void initialize() {
                frmSundialGenerator = new JFrame();
                frmSundialGenerator.setTitle("Sundial Generator");
                frmSundialGenerator.setResizable(false);
                frmSundialGenerator.setBounds(100, 100, 581, 349);
                frmSundialGenerator.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                
                // Sundial Generator title label                
                JLabel lblSundialGenerator = new JLabel(new ImageIcon(getClass().getResource("images/TitleBanner.jpg")));
                
                lblSundialGenerator.setHorizontalAlignment(SwingConstants.CENTER);
                frmSundialGenerator.getContentPane().add(lblSundialGenerator, BorderLayout.NORTH);
                
                // Establish South panel
                JPanel southPanel = new JPanel();
                southPanel.setBorder(new LineBorder(new Color(0, 0, 0)));
                frmSundialGenerator.getContentPane().add(southPanel, BorderLayout.SOUTH);
                southPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
                
                // Main data input panel
                JPanel panel = new JPanel();
                panel.setBorder(new LineBorder(new Color(0, 0, 0)));
                frmSundialGenerator.getContentPane().add(panel, BorderLayout.CENTER);
                panel.setLayout(new FormLayout(new ColumnSpec[] {
                                ColumnSpec.decode("434px:grow"),},
                        new RowSpec[] {
                                RowSpec.decode("25px"),
                                FormFactory.RELATED_GAP_ROWSPEC,
                                FormFactory.DEFAULT_ROWSPEC,
                                FormFactory.RELATED_GAP_ROWSPEC,
                                FormFactory.DEFAULT_ROWSPEC,
                                FormFactory.RELATED_GAP_ROWSPEC,
                                RowSpec.decode("max(11dlu;default)"),
                                FormFactory.RELATED_GAP_ROWSPEC,
                                FormFactory.DEFAULT_ROWSPEC,
                                FormFactory.RELATED_GAP_ROWSPEC,
                                FormFactory.DEFAULT_ROWSPEC,
                                FormFactory.RELATED_GAP_ROWSPEC,
                                RowSpec.decode("max(15dlu;default)"),
                                FormFactory.RELATED_GAP_ROWSPEC,}));
                
                // Status label
                final JLabel lblStatusReady = new JLabel("Status: Ready");
                lblStatusReady.setBackground(UIManager.getColor("Label.background"));
                lblStatusReady.setForeground(Color.RED);
                lblStatusReady.setFont(new Font("Tahoma", Font.BOLD, 14));
                lblStatusReady.setHorizontalAlignment(SwingConstants.CENTER);
                panel.add(lblStatusReady, "1, 1, fill, center");
                
                // Date label
                JLabel lblDate = new JLabel("Daylight Savings Time & Date");
                lblDate.setFont(new Font("Tahoma", Font.BOLD, 11));
                panel.add(lblDate, "1, 3, center, default");
                
                // DST Panel
                JPanel panel_4 = new JPanel();
                panel.add(panel_4, "1, 5, fill, fill");
                panel_4.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
                
                JLabel lblUseDst = new JLabel("Use DST:");
                panel_4.add(lblUseDst);
                
                // DST Selector
                final JComboBox comboBox_4 = new JComboBox();
                comboBox_4.setModel(new DefaultComboBoxModel(new String[] {"No", "Yes"}));
                panel_4.add(comboBox_4);
                
                // Date input panel
                JPanel panel_1 = new JPanel();
                panel.add(panel_1, "1, 7, fill, center");
                panel_1.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
                
                // Default date combobox
                final JComboBox comboBox_1 = new JComboBox();
                comboBox_1.setModel(new DefaultComboBoxModel(new String[] {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31"}));
                comboBox_1.setMaximumRowCount(5);
                
                // Month combobox
                final JComboBox comboBox = new JComboBox();
                comboBox.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent arg0) {
                                
                                Calendar cal = Calendar.getInstance();
                                
                                // CHANGE DATE COMBOBOX ACCORDING TO THE CHOSEN MONTH
                                switch (comboBox.getSelectedIndex())
                                {
                                        case 1: 
                                                if ((cal.get(Calendar.YEAR))%4 == 0)
                                                {
                                                        comboBox_1.setModel(new DefaultComboBoxModel(new String[] {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29"}));
                                                }
                                                else
                                                {
                                                        comboBox_1.setModel(new DefaultComboBoxModel(new String[] {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28"}));
                                                }
                                                break;
                                        case 3: comboBox_1.setModel(new DefaultComboBoxModel(new String[] {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30"}));
                                                break;
                                        case 5: comboBox_1.setModel(new DefaultComboBoxModel(new String[] {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30"}));
                                                break;
                                        case 8: comboBox_1.setModel(new DefaultComboBoxModel(new String[] {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30"}));
                                                break;
                                        case 10: comboBox_1.setModel(new DefaultComboBoxModel(new String[] {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30"}));
                                                break;
                                        default: comboBox_1.setModel(new DefaultComboBoxModel(new String[] {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31"}));
                                                break;
                                }
                        }
                });
                comboBox.setModel(new DefaultComboBoxModel(new String[] {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}));
                comboBox.setMaximumRowCount(5);
                panel_1.add(comboBox);
                panel_1.add(comboBox_1);
                
                // Option to use today's date
                final JCheckBox chckbxUseTodaysDate = new JCheckBox("Use Today's Date");
                panel_1.add(chckbxUseTodaysDate);
                chckbxUseTodaysDate.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                            if (chckbxUseTodaysDate.isSelected())
                            {
                                    //lblStatusReady.setText("Status: Using today's date!");
                                    comboBox.setEnabled(false);
                                    comboBox_1.setEnabled(false);
                            }
                            else if (!chckbxUseTodaysDate.isSelected())
                            {
                                    //lblStatusReady.setText("Status: Not using today's date!");
                                    comboBox.setEnabled(true);
                                    comboBox_1.setEnabled(true);
                            }
                    }
                });
                
                // Location Status
                final JLabel lblLocationStatus = new JLabel("Location: No location entered");
                lblLocationStatus.setForeground(Color.RED);
                panel.add(lblLocationStatus, "1, 9, center, default");
                
                // Where Are You Located Label
                final JLabel lblWhereAreYou = new JLabel("Where are you located?");
                lblWhereAreYou.setFont(new Font("Tahoma", Font.BOLD, 11));
                panel.add(lblWhereAreYou, "1, 11, center, default");
                
                // Generate Sundial button
                final JButton btnGenerateSundial = new JButton("Generate Sundial");
                btnGenerateSundial.setEnabled(false);
                btnGenerateSundial.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent arg0) {
                                
                                // Parse DST input
                                int dst = comboBox_4.getSelectedIndex();
                                
                                //
                                // BEGIN DATE CALCULATIONS
                                //
                                Calendar cal = Calendar.getInstance();
                                int year = 0;
                                year = cal.get(Calendar.YEAR);
                                int month = 0;
                                int day = 0;
                                
                                // User selected to use today's date
                                if (chckbxUseTodaysDate.isSelected())
                                {
                                        //Java starts counting months from 0
                                        //http://docs.oracle.com/javase/6/docs/api/java/util/Calendar.html#MONTH
                                        month = cal.get(Calendar.MONTH) + 1;
                                        day = cal.get(Calendar.DATE);
                                }
                                // User chose their own dates
                                else
                                {
                                        // Initializing month and day variables
                                        month = comboBox.getSelectedIndex() + 1;
                                        day = comboBox_1.getSelectedIndex() + 1;
                                }
                                
                                //
                                // END DATE CALCULATIONS
                                //
                                
                                //
                                // BEGIN INPUT PROCESSING
                                //
                                try
                                {
                                                // Initializing longitude and latitude variables from inputs
                                                latitude = CoordFinder.getLatitude(location);
                                                longitude = CoordFinder.getLongitude(location);
                                                
                                                
                                                if (location.equals("mars"))
                                                {
                                                        latitude = 40.75;
                                                longitude = -9.46;
                                                }
                                                
                                        
                                        // Longitude and Latitude input validity checking
                                        if (latitude < 20 || latitude > 70)
                                        {
                                                        lblStatusReady.setText("Status: Latitudes lower than 20 and higher than 70 degrees not supported!");
                                        }
                                        else if (latitude > 70 && longitude > 180)
                                        {
                                                lblStatusReady.setText("Status: Invalid latitude and longitude!");
                                        }
                                        else if (longitude > 180)
                                        {
                                                lblStatusReady.setText("Status: Invalid longitude!");
                                        }
                                        else if (location.equals("mars"))
                                        {
                                                ////////////////////////////////////////////////
                                                //                                            //
                                                //                                            //
                                                //   ENTER MARS CALCULATIONS HERE             //
                                                //                                            //
                                                //                                            //
                                                ////////////////////////////////////////////////
                                                
                                           JFrame f = new JFrame();
                                            final Drawing d = new Drawing();
                                            try{
                                                    boolean DST = dst == 1;
                                                    d.sendMarsLocation(0, 39.7, month, day, year);
                                                    JButton savebtn = new JButton("Save");
                                                    savebtn.setActionCommand("save");
                                                    savebtn.addActionListener(new ActionListener() {
                                                        public void actionPerformed(ActionEvent e) {
                                                                if ("save".equals(e.getActionCommand())){
                                                                    File saveFile = new File("savedimage.jpg");
                                                                    if (true) {
                                                                        try {
                                                                            BufferedImage bi = new BufferedImage(d.getWidth(), d.getHeight(), BufferedImage.TYPE_INT_RGB);      
                                                                            Graphics g = bi.createGraphics();
                                                                            d.paint(g);
                                                                            try {
                                                                            	ImageIO.write(bi, "jpg", saveFile);
                                                                            } catch (IOException ex) {
                                                                            }
                                                                        } catch (Exception ex) {
                                                                            ex.printStackTrace();
                                                                        }
                                                                    }
                                                                }
                                                        }
                                                    });
                                                    savebtn.setHorizontalAlignment(SwingConstants.CENTER);
                                                    f.getContentPane().add(savebtn, BorderLayout.SOUTH);
                                                    f.getContentPane().add(d, BorderLayout.CENTER);
                                                    f.setSize(900, 400);
                                                    f.setVisible(true);
                                                    String name = "Mars Sundial";
                                                    Properties properties = new Properties();
                                                    PrintJob pj = Toolkit.getDefaultToolkit().getPrintJob(f, name, properties);
                                                    if (pj != null) {
                                                            f.printAll(pj.getGraphics());
                                                            pj.end();
                                                    }
                                            }catch(NumberFormatException error){
                                                    
                                            }
                                                
                                        }
                                        // Received valid inputs
                                        else
                                        {
                                                lblStatusReady.setText("Status: Drawing..");
                                                
                                                /////////////////////////////////////////////////////////
                                                //                                                     //
                                                // BEGIN SUNDIAL GENERATION CODE                       //
                                                //                                                     //
                                                // CURRENT AVAILABLE VARIABLES:                        //
                                                //  - date : User selected date in yyyymmdd int format //
                                                //  - month : Month in integer format                  //
                                                //  - day : day in integer format                      //
                                                //  - year : year in integer format                    //
                                                //  - latitude : Latitude as a double                  //
                                                //  - longitude : Longitude as a double                //
                                                //  - dst : [0] - No                                   //
                                                //          [1] - Yes                                  //
                                                //                                                     //
                                                /////////////////////////////////////////////////////////
                                                
                                                
                                                JFrame f = new JFrame();
                                                        final Drawing d = new Drawing();
                                                        try{
                                                                boolean DST = dst == 1;
                                                                d.sendLocation(longitude, latitude, month, day, year, DST);
                                                                JButton savebtn = new JButton("Save");
                                                                savebtn.setActionCommand("save");
                                                                savebtn.addActionListener(new ActionListener() {
                                                                    public void actionPerformed(ActionEvent e) {
                                                                            if ("save".equals(e.getActionCommand())){
                                                                                File saveFile = new File("savedimage.jpg");
                                                                                if (true) {
                                                                                    try {
                                                                                        BufferedImage bi = new BufferedImage(d.getWidth(), d.getHeight(), BufferedImage.TYPE_INT_RGB);      
                                                                                        Graphics g = bi.createGraphics();
                                                                                        d.paint(g);
                                                                                        try {
                                                                                        	ImageIO.write(bi, "jpg", saveFile);
                                                                                        } catch (IOException ex) {
                                                                                        }
                                                                                    } catch (Exception ex) {
                                                                                        ex.printStackTrace();
                                                                                    }
                                                                                }
                                                                            }
                                                                    }
                                                                });
                                                                savebtn.setHorizontalAlignment(SwingConstants.CENTER);
                                                                f.getContentPane().add(savebtn, BorderLayout.SOUTH);
                                                                f.getContentPane().add(d, BorderLayout.CENTER);
//                                                                f.add(d);
                                                                f.setSize(900, 400);
                                                                f.setVisible(true);
                                                                String name = "Sundial";
                                                                Properties properties = new Properties();
                                                                PrintJob pj = Toolkit.getDefaultToolkit().getPrintJob(f, name, properties);
                                                                if (pj != null) {
                                                                        f.printAll(pj.getGraphics());
                                                                        pj.end();
                                                                }
                                                        }catch(NumberFormatException error){
                                                                
                                                        }
                                                
                                                ///////////////////////////////////////////////////////
                                                //                                                   //
                                                // END SUNDIAL GENERATION CODE                       //
                                                //                                                   //
                                                ///////////////////////////////////////////////////////
                                                Thread.sleep(1000);
                                                lblStatusReady.setText("Status: Complete!");
                                        }
                                }
                                // Catches interrupt exception for the Thread.sleep() command
                                catch (InterruptedException e)
                                {
                                        // Do nothing for now
                                }
                                //
                                // END INPUT PROCESSING
                                //
                                
                        }
                });
                

                
                // Location input text box
                txtEnterALocation = new JTextField();
                txtEnterALocation.addFocusListener(new FocusAdapter() {
                        @Override
                        public void focusGained(FocusEvent arg0) {
                                txtEnterALocation.setText("");
                                lblLocationStatus.setText("Location: No location entered");
                                lblStatusReady.setText("Status: Ready");
                                btnGenerateSundial.setEnabled(false);
                        }
                        @Override
                        public void focusLost(FocusEvent e) {
                                if (txtEnterALocation.getText().equals(""))
                                {
                                        txtEnterALocation.setText("Enter a location identifier...");
                                }
                        }
                });
                txtEnterALocation.setText("Enter a location identifier...");
                panel.add(txtEnterALocation, "1, 13, center, default");
                txtEnterALocation.setColumns(40);
                
                // Validate Location Button
                JButton btnValidateLocation = new JButton("Validate Location");
                btnValidateLocation.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent arg0) {
                                
                                location = txtEnterALocation.getText();
                                
                                // VALIDATE LOCATION
                                if (txtEnterALocation.getText().toLowerCase().contains("mars") || txtEnterALocation.getText().toLowerCase().contains("cydonia"))
                                {
                                        // Update status
                                        lblStatusReady.setText("Status: Location valid! Ready to generate!");
                                        // Update Location
                                        lblLocationStatus.setText("Location: Cydonia on the planet of Mars");
                                        // ENABLE GENERATE SUNDIAL
                                        btnGenerateSundial.setEnabled(true);
                                        location = "mars";
                                }
                                else if (CoordFinder.getAddress(txtEnterALocation.getText()) == null)
                                {
                                        lblStatusReady.setText("Status: Invalid Location!");
                                        lblLocationStatus.setText("Location: Invalid Location!");
                                }
                                else
                                {
                                        // Update status
                                        lblStatusReady.setText("Status: Location valid! Ready to generate!");
                                        // Update Location
                                        lblLocationStatus.setText("Location: " + CoordFinder.getAddress(location));
                                        // ENABLE GENERATE SUNDIAL
                                        btnGenerateSundial.setEnabled(true);
                                }
                                
                                
                        }
                });
                southPanel.add(btnValidateLocation);
                southPanel.add(btnGenerateSundial);
        }
}

